package com.bestcem.xm.label.dao.impl.mysql;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.common.core.uitls.StringUtil;
import com.bestcem.xm.label.dao.LabelDao;
import com.bestcem.xm.label.dao.mapper.LabelMapper;
import com.bestcem.xm.label.entity.mongo.Label;
import com.bestcem.xm.label.entity.mysql.LabelCountEntity;
import com.bestcem.xm.label.entity.mysql.LabelEntity;
import com.bestcem.xm.label.entity.pojo.LabelDO;
import com.bestcem.xm.label.service.dto.label.LabelDTO;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 标签数据访问层
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/5/21
 */

@Repository
public class LabelDaoImpl implements LabelDao {

    @Resource
    private LabelMapper labelMapper;

    @Override
    public Integer countByNameAndOrgId(String name, String orgId) {
        return labelMapper.countByOrgIdAndName(orgId, name);
    }

    @Override
    public String save(LabelDO labelDO) {
        labelDO.setLabelId(StringUtil.getId());
        labelMapper.createLabel(LabelDO.toEntity(labelDO));
        // LabelEntity labelEntity = labelMapper.findById(labelDO.getLabelId());
        return labelDO.getLabelId();
    }

    @Override
    public LabelDO getById(String id) {
        LabelEntity labelEntity = labelMapper.findById(id);
        return LabelDO.toDo(labelEntity);
    }

    @Override
    public Boolean updateLabel(LabelDO labelDO) {
        labelMapper.updateLabel(LabelDO.toEntity(labelDO));
        return true;
    }

    @Override
    public Boolean delete(String id) {
        labelMapper.deleteById(id);
        return true;
    }

    @Override
    public List<LabelDO> deleteAndListByLabelGroupId(@Nullable String orgId, @NotNull String labelGroupId) {
        // 1.find
        List<LabelEntity> entities = labelMapper.findByLabelGroupId(labelGroupId);
        // 2.delete
        labelMapper.deleteByLabelGroupId(labelGroupId);
        if (CollUtil.isNotEmpty(entities)) {
            entities.stream().map(entity -> LabelDO.toDo(entity)).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    public List<LabelDTO> listByIds(List<String> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }

        return labelMapper.listLabels(ids);
    }

    @Override
    public List<LabelDTO> listByLabelGroupIds(List<String> groupIds) {
        if (CollectionUtil.isEmpty(groupIds)) {
            return Collections.emptyList();
        }

        return labelMapper.listByLabelGroupIds(groupIds);
    }

    @Override
    public LabelDO insertOrReplace(LabelDO labelDO) {
        labelDO.setUpdateTime(DateUtil.getCommonDate());
        LabelEntity entity = labelMapper.findByLabelGroupIdAndName(labelDO.getLabelGroupId(), labelDO.getName());

        if (entity != null) {
            // 更新
            labelDO.setLabelId(entity.getLabelId());
            labelMapper.updateLabel(LabelDO.toEntity(labelDO));
        } else {
            // 插入
            labelDO.setCreateTime(DateUtil.getCommonDate());
            labelDO.setLabelId(StringUtil.getId());
            labelMapper.createLabel(LabelDO.toEntity(labelDO));
        }
        entity = labelMapper.findById(labelDO.getLabelId());
        return LabelDO.toDo(entity);
    }

    @Override
    public List<LabelDO> listByOrgId(String orgId) {
        List<LabelEntity> entities = labelMapper.findByOrgId(orgId);
        if (CollUtil.isNotEmpty(entities)) {
            return entities.stream().map(entity -> LabelDO.toDo(entity)).collect(Collectors.toList());
        }
        return new ArrayList<LabelDO>();
    }

    @Override
    public void batchSaveSampleData(List<LabelDO> newLabelList) {
        if (CollUtil.isNotEmpty(newLabelList)) {
            List<LabelEntity> labelEntities =
                    newLabelList.stream().map(LabelDO::toEntity).collect(Collectors.toList());
            labelMapper.batchSaveSampleData(labelEntities);
        }
    }

    /**
     * 统计标签数
     *
     * @param ids
     * @return
     */
    @Override
    public long countByIds(Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return 0;
        }

        return labelMapper.countByIds(ids);
    }

    @Override
    public Long countByOrgId(String orgId) {
        return labelMapper.countByOrgId(orgId);
    }

    @Override
    public List<LabelDO> listByOrgId(String orgId, Integer offset, Integer size) {
        List<LabelEntity> entities = labelMapper.listByOrgId(orgId, offset, size);
        if (CollUtil.isNotEmpty(entities)) {
            return entities.stream().map(entity -> LabelDO.toDo(entity)).collect(Collectors.toList());
        }
        return new ArrayList<LabelDO>();
    }

    @Override
    public List<LabelDO> listByOrgIdAndIds(String orgId, List<String> labelIds) {
        if (CollectionUtil.isEmpty(labelIds)) {
            return new ArrayList<LabelDO>();
        }
        List<LabelEntity> entities = labelMapper.listByOrgIdAndIds(orgId,labelIds);
        if (CollUtil.isNotEmpty(entities)) {
            return entities.stream().map(entity -> LabelDO.toDo(entity)).collect(Collectors.toList());
        }
        return new ArrayList<LabelDO>();
    }

    @Override
    public List<LabelDO> listByLabelNames(String orgId, List<String> labelNames) {
        if (CollectionUtils.isEmpty(labelNames)){
            return new ArrayList<LabelDO>();
        }
        List<LabelEntity> entities = labelMapper.listByLabelNames(orgId,labelNames);
        if (CollUtil.isNotEmpty(entities)) {
            return entities.stream().map(entity -> LabelDO.toDo(entity)).collect(Collectors.toList());
        }
        return new ArrayList<LabelDO>();
    }

    @Override
    public Map<String, Integer> countByLabelGroupIds(String orgId, Set<String> labelGroupIds) {
        if(CollectionUtils.isEmpty(labelGroupIds)){
            return new HashMap<>();
        }
        Map<String, Integer> groupIdAndLabelCountMap = new HashMap<>();
        List<LabelCountEntity> countEntities = labelMapper.countByOrgIdAndLabelGroupIds(orgId, labelGroupIds);
        if (CollectionUtil.isNotEmpty(countEntities)) {
            countEntities.stream().forEach(item -> {
                groupIdAndLabelCountMap.put(item.getLabelGroupId(), item.getCount());
            });
        }
        return groupIdAndLabelCountMap;
    }

    @Override
    public Collection<LabelDO> batchSave(Collection<LabelDO> insertedLabels) {
        if (CollUtil.isNotEmpty(insertedLabels)) {
            List<LabelEntity> labelEntities = insertedLabels.stream().map(item -> {
                item.setLabelId(StringUtil.getId());
                return LabelDO.toEntity(item);
            }).collect(Collectors.toList());
            labelMapper.batchSave(labelEntities);
            return insertedLabels;
        }
        return new ArrayList<>();
    }

    @Override
    public void batchUpdate(Collection<LabelDO> updatedLabels) {
        if (CollUtil.isNotEmpty(updatedLabels)) {
            List<LabelEntity> labelEntities = updatedLabels.stream().map(item -> {
                return LabelDO.toEntity(item);
            }).collect(Collectors.toList());
            labelMapper.batchUpdate(labelEntities);
        }
    }

    private LabelEntity convert(Label label){
        LabelEntity entity = new LabelEntity();
        entity.setLabelId(label.getId());
        entity.setOrgId(label.getId());
        entity.setName(label.getId());
        entity.setAuto(label.getAuto() ? 1 : 0);
        entity.setManual(label.getManual() ? 1 : 0);
        entity.setLabelGroupId(label.getId());
        entity.setCreateTime(label.getCreateTime());
        entity.setUpdateTime(label.getUpdateTime());
        return entity;
    }
}
